﻿using DTcms.Core.Common.Emum;
using DTcms.Core.Common.Helper;
using DTcms.Core.Common.Extensions;
using DTcms.Core.Model.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace DTcms.Core.DBFactory.Database
{
    public class AppDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int,
        ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim, ApplicationUserToken>
    {
        private readonly DBType _dbType;
        private readonly string _connectionString = string.Empty;
        /// <summary>
        /// 默认连接写数据库
        /// </summary>
        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) {
            _dbType = Appsettings.GetValue(new string[] { "ConnectionStrings", "DBType" }).ToEnum<DBType>();//数据库类型
            _connectionString = Appsettings.GetValue(new string[] { "ConnectionStrings", "WriteConnection" });//连接字符串
        }
        /// <summary>
        /// 指定读写分离模式连接
        /// </summary>
        public AppDbContext(DBType? dbType, string? connectionString)
        {
            _dbType = dbType ?? DBType.SqlServer; //数据库类型
            _connectionString = connectionString ?? String.Empty; //连接字符串
        }

        #region 实体到表的映射===========================
        //系统
        public DbSet<SysConfig>? dt_sysconfig { get; private set; }
        public DbSet<Sites>? dt_sites { get; private set; }
        public DbSet<SiteDomain>? dt_site_domain { get; private set; }
        public DbSet<SiteChannel>? dt_site_channel { get; private set; }
        public DbSet<SiteChannelField>? dt_site_channel_field { get; private set; }
        public DbSet<SitePayment>? dt_site_payment { get; private set; }
        public DbSet<Manager>? dt_manager { get; private set; }
        public DbSet<ManagerLog>? dt_manager_log { get; private set; }
        public DbSet<ManagerMenu>? dt_manager_menu { get; private set; }
        public DbSet<ManagerMenuModel>? dt_manager_menu_model { get; private set; }
        public DbSet<Payments>? dt_payments { get; private set; }
        public DbSet<PaymentCollection>? dt_payment_collection { get; private set; }
        public DbSet<Areas>? dt_areas { get; private set; }
        public DbSet<NotifyTemplate>? dt_notify_template { get; private set; }
        //文章
        public DbSet<Articles>? dt_articles { get; private set; }
        public DbSet<ArticleFieldValue>? dt_article_field_value { get; private set; }
        public DbSet<ArticleCategory>? dt_article_category { get; private set; }
        public DbSet<ArticleCategoryRelation>? dt_article_category_relation { get; private set; }
        public DbSet<ArticleLabel>? dt_article_label { get; private set; }
        public DbSet<ArticleLabelRelation>? dt_article_label_relation { get; private set; }
        public DbSet<ArticleComment>? dt_article_comment { get; private set; }
        public DbSet<ArticleCommentLike>? dt_article_comment_like { get; private set; }
        public DbSet<ArticleAlbum>? dt_article_album { get; private set; }
        public DbSet<ArticleAttach>? dt_article_attach { get; private set; }
        public DbSet<ArticleLike>? dt_article_like { get; private set; }
        public DbSet<ArticleContribute>? dt_article_contribute { get; private set; }
        //会员
        public DbSet<Members>? dt_members { get; private set; }
        public DbSet<MemberAddress>? dt_member_address { get; private set; }
        public DbSet<MemberGroup>? dt_member_group { get; private set; }
        public DbSet<MemberMessage>? dt_member_message { get; private set; }
        public DbSet<MemberRecharge>? dt_member_recharge { get; private set; }
        public DbSet<MemberPointLog>? dt_member_point_log { get; private set; }
        public DbSet<MemberAmountLog>? dt_member_amount_log { get; private set; }
        public DbSet<MemberAttachLog>? dt_member_attach_log { get; private set; }
        #endregion

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //默认只写了三种数据库，有需要自行加
            switch (_dbType)
            {
                case DBType.MySql:
                    optionsBuilder.UseMySql(_connectionString, ServerVersion.AutoDetect(_connectionString));
                    break;
                case DBType.Oracle:
                    optionsBuilder.UseOracle(_connectionString);
                    break;
                default:
                    optionsBuilder.UseSqlServer(_connectionString);
                    break;
            }
        }

        /// <summary>
        /// 模型构建器
        /// </summary>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            //用户导航属性与外链关系
            modelBuilder.Entity<ApplicationUser>(b =>
            {
                b.HasMany(e => e.Claims).WithOne(e => e.User).HasForeignKey(uc => uc.UserId).IsRequired();
                b.HasMany(e => e.Logins).WithOne(e => e.User).HasForeignKey(ul => ul.UserId).IsRequired();
                b.HasMany(e => e.Tokens).WithOne(e => e.User).HasForeignKey(ut => ut.UserId).IsRequired();
                b.HasMany(e => e.UserRoles).WithOne(e => e.User).HasForeignKey(ur => ur.UserId).IsRequired();
            });
            modelBuilder.Entity<ApplicationRole>(b =>
            {
                b.HasMany(e => e.UserRoles).WithOne(e => e.Role).HasForeignKey(ur => ur.RoleId).IsRequired();
                b.HasMany(e => e.RoleClaims).WithOne(e => e.Role).HasForeignKey(rc => rc.RoleId).IsRequired();
            });

            //配置实体类型映射到的表名
            modelBuilder.Entity<ApplicationUser>().ToTable("dt_users");
            modelBuilder.Entity<ApplicationRole>().ToTable("dt_roles");
            modelBuilder.Entity<ApplicationUserLogin>().ToTable("dt_user_logins");
            modelBuilder.Entity<ApplicationUserClaim>().ToTable("dt_user_claims");
            modelBuilder.Entity<ApplicationUserRole>().ToTable("dt_user_roles");
            modelBuilder.Entity<ApplicationRoleClaim>().ToTable("dt_role_claims");
            modelBuilder.Entity<ApplicationUserToken>().ToTable("dt_user_tokens");

            //添加种子数据
            IList<ApplicationRole>? roleList = JsonHelper.ToJson<IList<ApplicationRole>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_roles.json")));
            if (roleList != null)
            {
                modelBuilder.Entity<ApplicationRole>().HasData(roleList);
            }
            
            IList<ApplicationUser>? userList = JsonHelper.ToJson<IList<ApplicationUser>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_users.json")));
            if(userList != null)
            {
                modelBuilder.Entity<ApplicationUser>().HasData(userList);
            }
            
            IList<ApplicationUserRole>? userRoleList = JsonHelper.ToJson<IList<ApplicationUserRole>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_user_roles.json")));
            if(userRoleList != null)
            {
                modelBuilder.Entity<ApplicationUserRole>().HasData(userRoleList);
            }
            
            IList<Manager>? managerList = JsonHelper.ToJson<IList<Manager>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_manager.json")));
            if (managerList != null)
            {
                modelBuilder.Entity<Manager>().HasData(managerList);
            }
            
            IList<SysConfig>? configList = JsonHelper.ToJson<IList<SysConfig>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_sysconfig.json")));
            if (configList != null)
            {
                modelBuilder.Entity<SysConfig>().HasData(configList);
            }
            
            IList<Sites>? siteList = JsonHelper.ToJson<IList<Sites>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_sites.json")));
            if (siteList != null)
            {
                modelBuilder.Entity<Sites>().HasData(siteList);
            }
            
            IList<ManagerMenuModel>? modelList = JsonHelper.ToJson<IList<ManagerMenuModel>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_manager_menu_model.json")));
            if (modelList != null)
            {
                modelBuilder.Entity<ManagerMenuModel>().HasData(modelList);
            }
            
            IList<ManagerMenu>? menuList = JsonHelper.ToJson<IList<ManagerMenu>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_manager_menu.json")));
            if (menuList != null)
            {
                modelBuilder.Entity<ManagerMenu>().HasData(menuList);
            }
            
            IList<Payments>? payList = JsonHelper.ToJson<IList<Payments>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_payment.json")));
            if (payList != null)
            {
                modelBuilder.Entity<Payments>().HasData(payList);
            }

            IList<NotifyTemplate>? notifyList = JsonHelper.ToJson<IList<NotifyTemplate>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_notify_template.json")));
            if (notifyList != null)
            {
                modelBuilder.Entity<NotifyTemplate>().HasData(notifyList);
            }

            IList<MemberGroup>? groupList = JsonHelper.ToJson<IList<MemberGroup>>(File.ReadAllText(FileHelper.GetCurrPath(@"/DataSeed/dt_member_group.json")));
            if (groupList != null)
            {
                modelBuilder.Entity<MemberGroup>().HasData(groupList);
            }
        }
    }
}
